/*
 * Copyright (C) 2010-2101 Alibaba Group Holding Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.otter.manager.web.common.model;

import com.alibaba.otter.shared.common.model.config.channel.Channel;
import com.alibaba.otter.shared.common.model.config.node.NodeStatus;
import com.alibaba.otter.shared.common.model.config.pipeline.Pipeline;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.CollectionUtils;

import java.io.Serial;
import java.util.Collection;
import java.util.List;

/**
 * @author simon 2012-1-13 下午03:34:32
 */
@Setter
@Getter
public class SeniorChannel extends Channel {

    @Serial
    private static final long serialVersionUID = -5864547001482768341L;

    private boolean processEmpty;

    @JsonIgnore
    private transient PipelineStatus pipelineStatus;

    @JsonGetter
    public boolean getCanStart(){
        return pipelineStatus != null && pipelineStatus.canStart() && processEmpty;
    }

    @JsonGetter
    public String getStatusDesc(){
        if (!processEmpty){
            return "process里面还有同步数据，请直接停止channel";
        }
        return pipelineStatus != null? pipelineStatus.desc() : "";
    }


    public void setPipelines(List<Pipeline> pipelines){
        super.setPipelines(pipelines);
        this.pipelineStatus = new PipelineStatus(pipelines);
    }

    public static class PipelineStatus{

        private boolean selectRunning = false;

        private boolean extractRunning = false;

        private boolean loadRunning = false;

        public PipelineStatus(List<Pipeline> pipelines){

            if (CollectionUtils.isEmpty(pipelines)){
                return;
            }
            this.extractRunning = pipelines.stream().map(Pipeline::getExtractNodes).flatMap(Collection::stream)
                    .filter(n -> n.getStatus() == NodeStatus.START).count() == pipelines.size();

            this.selectRunning = pipelines.stream().map(Pipeline::getSelectNodes).flatMap(Collection::stream)
                    .filter(n -> n.getStatus() == NodeStatus.START).count() == pipelines.size();

            this.loadRunning = pipelines.stream().map(Pipeline::getLoadNodes).flatMap(Collection::stream)
                    .filter(n -> n.getStatus() == NodeStatus.START).count() == pipelines.size();

        }

        public String desc(){
            String desc = (selectRunning ? "S" : "") + (extractRunning ? "E" : "") + (loadRunning ? "L" : "");
            return StringUtils.isBlank(desc)? desc : desc + "节点未启动";
        }

        public boolean canStart(){
            return selectRunning && extractRunning && loadRunning;
        }

    }
}
